#include "RR.h"
#include "linkedList.h"
#include <sys/times.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

#include <unistd.h>
#include <stdlib.h>

void rr(struct jobNode **ready, struct jobNode **job, clock_t start, int *alarm_policy){

    struct jobNode *temp_job;
    struct jobNode *temp_ready;
    clock_t end;
    struct tms tmsend;
    static long clktck = 0;
    //int dirtybit = 0;
    int condition;
    //temp_job = job;

    end = times(&tmsend);
    //get system clock tick per second
    if (clktck == 0)
        if ((clktck = sysconf(_SC_CLK_TCK)) < 0) {
            perror("sysconf error");
            exit(-1);
        }
    // enqueue new arrived job before enqueuing old job
    temp_ready = *ready;
    while((*job != NULL) && (*job)->arrivalTime <= (int)((end-start)/clktck)){
        (*job)->quantum = 2;
        if(temp_ready != NULL){
            while(temp_ready->ready_next != NULL)
                temp_ready = temp_ready->ready_next;
            temp_ready->ready_next = *job;
        }else{
            *ready = *job;
            temp_ready = *job;
        }
        *job = (*job)->next;
    }

    condition = 0;

    if ((*ready != NULL) && ((*ready)->timeRemain > 0 && (*ready)->runinfinity == 0))
        condition = 1;

    if ((*ready != NULL) && ((*ready)->timeRemain < 0 && (*ready)->runinfinity == 1))
        condition = 2;

    if ((*ready != NULL) && ((*ready)->timeRemain <= 0 && (*ready)->runinfinity == 0)){
        condition = 3;
        (*ready)->quantum = 0;
    }

    if ((*ready != NULL) && ((*ready)->timeRemain == 0 && (*ready)->runinfinity == 1)){
        condition = 4;
        (*ready)->quantum = 0;
    }

    if(*ready != NULL && (*ready)->quantum == 0){
        // condition 1 not_infin. still running TSTPed
        // condition 2 infin. still running TSTPed
        // condition 3 not_infin. not running
        // condition 4 infin. not running


        // dequeue first
        if (*ready != NULL && (condition == 4 || condition == 3)){
            *ready = (*ready)->ready_next;
        }

        // enqueue old job
        if (*ready != NULL && (condition == 2 || condition == 1)){
            (*ready)->quantum = 2;
            temp_ready = *ready;
            while(temp_ready->ready_next != NULL)
                temp_ready = temp_ready->ready_next;
            temp_ready->ready_next = *ready;
            if ((*ready)->ready_next != NULL){
                *ready = (*ready)->ready_next;
                temp_ready->ready_next->ready_next = NULL;
            }else
                *ready = NULL;
        }
    }

    *alarm_policy = 1;
    if(*ready!=NULL){
        if ((*ready)->timeRemain < 2 && (*ready)->runinfinity == 0)
                (*ready)->quantum = 1;   // wont come here when timeRemain <= 0 or timeRemain >=2
   /* *alarm_policy = 2;   //infinite or timeRemain>2 --> normal cases
    if(*ready!=NULL){
        if ((*ready)->timeRemain < 2 && (*ready)->runinfinity == 0)
            *alarm_policy = 1;   // wont come here when timeRemain <= 0 or timeRemain >=2*/

     /*   if((*ready)->child_pid != 0) { // process is running
            // HERE NEED another clock tick ?
            end = times(&tmsend);
            kill((*ready)->child_pid,SIGCONT);
            // record the start timer
            (*ready)->timeline[(*ready)->timelineIndex][0] = (float)(end-start)/(float)clktck;
        }  */
    }
}
